// utils/http.js
// console.log(process,'process');

// 基础配置
const config = {
	baseURL: 'https://api.mszcdf.cn', // 'https://carpool-api.mlsxcxkf.com', // https://carpool-api.mlsxcxkf.com/
	timeout: 10000, // 请求超时时间
	header: {
		'Content-Type': 'application/json;charset=UTF-8' // 默认  
	}
}
let optionsObj = {}
// 请求队列（用于取消请求）
const requestQueue = new Map()

/**
 * 封装uni.request
 * @param {Object} options 请求配置
 * @returns {Promise} 返回Promise对象
 */
function request(options) {


	// 合并配置
	options = Object.assign({}, config, options)
	// 处理请求URL
	if (!options.url.startsWith('http') && !options.url.startsWith('https')) {

		options.url = config.baseURL + options.url
	}


	// 添加token到header
	const token = uni.getStorageSync('token')
	if (token) {
		options.header = options.header || {}
		options.header.Authorization = `Bearer ${token}`
		if (options.url.includes('upload')) {
			config.header['Content-Type'] = 'multipart/form-data'
		}

	}


	// 生成请求唯一标识（用于取消请求）
	const requestKey = `${options.method}_${options.url}_${JSON.stringify(options.data)}`
	optionsObj = options
	return new Promise((resolve, reject) => {
		// 添加到请求队列
		requestQueue.set(requestKey, { resolve, reject })

		// 发起请求
		const requestTask = uni.request({
			...options,
			success: (res) => {
				// 从队列中移除
				requestQueue.delete(requestKey)

				// 响应拦截处理
				handleResponse(res, resolve, reject)
			},
			fail: (err) => {
				// 从队列中移除
				requestQueue.delete(requestKey)

				// 错误处理
				handleError(err, reject)
			},
			complete: () => {
				// 可以在这里处理loading状态等
			}
		})

		// 如果需要取消请求，可以保存requestTask
		requestQueue.get(requestKey).task = requestTask
	})
}

/**
 * 处理响应
 */
function handleResponse(res, resolve, reject) {
	// console.log(res, '处理响应');

	const { statusCode, data, errMsg } = res

	// 状态码判断
	if (statusCode == 200) {

		// 业务状态码处理 （根据后端接口规范调整）
		if (data.err == 0) {

			resolve(data)
		} else {
			// 业务错误处理
			handleBusinessError(data, reject)
		}
	} else {
		// HTTP状态码错误处理
		handleHttpError(statusCode, reject)
	}
}

/**
 * 处理业务错误
 */
function handleBusinessError(data, reject) {
	console.log('处理业务错误', data);

	const { err, msg, data: data2 } = data

	// 未登录或token过期
	if (err === 401 || err === 403) {
		uni.showToast({
			title: '登录已过期，请重新登录',
			icon: 'none'
		})
		// 清除token
		uni.removeStorageSync('token')

		// 跳转到首页
		uni.redirectTo({
			url: '/pages/login/bindPhone?from=' + window.location.hash
		})
		return
	}
	if (err == 10001) {
		uni.showModal({
			title: '提示',
			content: msg,
			cancelText: '取消',
			confirmText: '去支付',
			success: (res) => {
				if (res.confirm) {
					uni.navigateTo({
						url: '/pages/personalCenter/trip/owners/tripDetails?id=' + data2.line_id
					})
				}
			}
		})
		return
	}


	let title = msg
	if (msg.includes('code been used')) title = '登录code失效，请重新点击登录'

	// 其他业务错误
	uni.showToast({
		title: title || '请求失败',
		icon: 'none',
		mask: true,
		duration: 3000 // 显示时间为 5 秒

	})

	reject(data)
}

/**
 * 处理HTTP错误
 */
function handleHttpError(statusCode, reject) {
	let errMessage = '请求失败'

	switch (statusCode) {
		case 400:
			errMessage = '请求错误'
			break
		case 401:
			errMessage = '未授权，请登录'
			break
		case 403:
			errMessage = '拒绝访问'
			break
		case 404:
			errMessage = '请求地址不存在'
			break
		case 500:
			errMessage = '服务器内部错误'
			break
		case 502:
			errMessage = '网关错误'
			break
		case 503:
			errMessage = '服务不可用'
			break
		case 504:
			errMessage = '网关超时'
			break
	}

	let title = errMessage
	if (errMessage.includes('code been used')) title = '登录code失效，请重新点击登录'


	uni.showToast({
		title: title,
		icon: 'none',
		mask: true
	})

	reject({ code: statusCode, message: errMessage })
}

/**
 * 处理网络错误
 */
function handleError(err, reject) {
	uni.showToast({
		title: '网络错误，请检查网络连接',
		icon: 'none'
	})

	reject({ code: -1, message: '网络错误' })
}

/**
 * 取消请求
 * @param {String} requestKey 请求唯一标识
 */
function cancelRequest(requestKey) {
	if (requestQueue.has(requestKey)) {
		const { task, reject } = requestQueue.get(requestKey)
		task.abort()
		reject({ code: -2, message: '请求已取消' })
		requestQueue.delete(requestKey)
	}
}

/**
 * 取消所有请求
 */
function cancelAllRequests() {
	requestQueue.forEach(({ task, reject }) => {
		task.abort()
		reject({ code: -2, message: '请求已取消' })
	})
	requestQueue.clear()
}
/**
 * 文件上传
 * @param {String} url 上传地址
 * @param {String} filePath 文件路径
 * @param {String} name 文件对应的key
 * @param {Object} formData 其他表单数据
 * @param {Object} options 其他配置
 */
function uploadFile(url, filePath, name = 'file', formData = {}, options = {}) {
	// 处理URL
	if (!url.startsWith('http') && !url.startsWith('https')) {
		url = config.baseURL + url
	}

	// 添加token
	const header = options.header || {}
	const token = uni.getStorageSync('token')
	if (token) {
		header.Authorization = `Bearer ${token}`,
			header['Content-Type'] = 'multipart/form-data'
	}

	return new Promise((resolve, reject) => {
		const uploadTask = uni.uploadFile({
			url,
			filePath,
			name,
			formData,
			header,
			success: (res) => {

				if (res.statusCode === 200) {
					try {
						const data = JSON.parse(res.data)
						resolve(data)
					} catch (e) {
						resolve(res.data)
					}
				} else {
					handleHttpError(res.statusCode, reject)
				}
			},
			fail: (err) => {
				handleError(err, reject)
			}
		})

		// 可以返回uploadTask以便监听进度
		options.onProgressUpdate && uploadTask.onProgressUpdate(options.onProgressUpdate)
	})
}


// 导出常用方法
export default {
	request,
	get(url, data, options = {}) {
		return request({
			url,
			data,
			method: 'GET',
			...options
		})
	},
	post(url, data, options = {}) {
		return request({
			url,
			data,
			method: 'POST',
			...options
		})
	},
	put(url, data, options = {}) {
		return request({
			url,
			data,
			method: 'PUT',
			...options
		})
	},
	delete(url, data, options = {}) {
		return request({
			url,
			data,
			method: 'DELETE',
			...options
		})
	},
	cancelRequest,
	cancelAllRequests,
	uploadFile
}